package worklog.servlets;

import java.io.IOException;
import java.io.PrintWriter;
import java.io.UnsupportedEncodingException;
import java.math.BigInteger;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.sql.SQLException;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import worklog.db.UserDB;

import worklog.dto.ResponseDTO;
import worklog.dto.UserDTO;

import com.mysql.jdbc.exceptions.jdbc4.MySQLNonTransientConnectionException;

@WebServlet("/login")
public class Login extends HttpServlet {
	private static final long serialVersionUID = 1L;
	private UserDB userDB;
	private ResponseDTO responder = new ResponseDTO();
	
    public Login() throws Exception{ super(); }
    
	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { 
		doGet(request, response);
	}

	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { 
		userDB = new UserDB();
		PrintWriter out = response.getWriter();
		response.setContentType("application/json");
    	if (userDB.isReady()) out.print(processRequest(request, response));
    	else out.print(responder.showError("DB connection error"));
    	userDB.close();
    	out.close();
	}
	
	private String processRequest(HttpServletRequest request, HttpServletResponse response){
		int paramLength = request.getParameterMap().size();
		HttpSession session = request.getSession();
    	if (paramLength > 0) {
    		String name = request.getParameter("username");
    		String pass = request.getParameter("password");
    		String hash = request.getParameter("hash");
    		if (pass == null) pass = hash;														// either password or hash should be given
    		if (name == null || pass == null) return responder.showError("Incorrect parameters");			// username and pass must not be empty
    		
    		UserDTO user = new UserDTO();
    		try{
    			user = userDB.LoginUser(name, pass);
    		}
    		catch(MySQLNonTransientConnectionException e){ return responder.showError("DB error"); }
    		catch(SQLException e){ return responder.showError("SQL error"); }
    		catch(Exception e){ e.printStackTrace(); return responder.showError("Unknown error"); }
    		
    		if (user != null && user.getLogin() != null){														// Log-In
    			session.setAttribute("userId", user.getId());
    			session.setAttribute("username", user.getLogin());
    			session.setAttribute("status", user.getStatus());
    			session.setAttribute("logged", true);
    			return responder.showSuccess(md5( user.getId() + user.getLogin() + user.getPassword() ));
    		}
    		else return responder.showError("Incorrect username or password");
    	}
    	else {																					// Log-Out
    		session.removeAttribute("userId");
    		session.removeAttribute("username");
    		session.removeAttribute("status");
    		session.removeAttribute("logged");
    		try { response.sendRedirect("login.jsp"); } catch (IOException e) {}
    		return responder.showSuccess();
    	}
	}
	
	
	/**
	 * md5 a string.
	 */
	private String md5(String input) {
		byte[] data = null;
		MessageDigest md = null;
		try { md = MessageDigest.getInstance("MD5"); } catch (NoSuchAlgorithmException e1){ e1.printStackTrace(); }
		try { data = input.getBytes("UTF-8"); } catch (UnsupportedEncodingException e1) { e1.printStackTrace(); }
		md.update(data, 0, data.length);
		BigInteger i = new BigInteger(1, md.digest());
		return i.toString(16);
	}

}